package Drivers;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import jaxb.contactinfo.*;
import jaxb.departmentemployees.*;
import jaxb.departmentmanagers.*;
import jaxb.departments.*;
import jaxb.employees.*;
import jaxb.employees.RowType;
import DAO.*;


public class EmployeesUnmarshaller  {
	private JAXBContext contactJax;
	private JAXBContext employeeJax;
	private JAXBContext depEmpJax;
	private JAXBContext depManJax;
	private JAXBContext departmentJax;
	private Unmarshaller contactUnmarsh;
	private Unmarshaller employeeUnmarsh;
	private Unmarshaller depEmpUnmarsh;
	private Unmarshaller depManUnmarsh;
	private Unmarshaller departmentsUnmarsh;
	
	
	public EmployeesUnmarshaller() throws JAXBException{
		//Create jaxbcontext instance for each objectfactory
		contactJax = JAXBContext.newInstance(jaxb.contactinfo.ObjectFactory.class);
		employeeJax = JAXBContext.newInstance(jaxb.employees.ObjectFactory.class);
		depEmpJax = JAXBContext.newInstance(jaxb.departmentemployees.ObjectFactory.class);
		depManJax = JAXBContext.newInstance(jaxb.departmentmanagers.ObjectFactory.class);
		departmentJax = JAXBContext.newInstance(jaxb.departments.ObjectFactory.class);
		
		//Creates unmarshaller for each jaxbcontext
		contactUnmarsh = contactJax.createUnmarshaller();
		employeeUnmarsh = employeeJax.createUnmarshaller();
		depEmpUnmarsh = depEmpJax.createUnmarshaller();
		depManUnmarsh = depManJax.createUnmarshaller();
		departmentsUnmarsh = departmentJax.createUnmarshaller();
	}
	
	private ContactinfoType getContactInfo(String fileName) throws JAXBException{
		return (ContactinfoType)((JAXBElement) contactUnmarsh.unmarshal(new File(fileName))).getValue();
	}
	private DepEmpType getDepartmentEmployee(String fileName) throws JAXBException{
		return (DepEmpType)((JAXBElement) depEmpUnmarsh.unmarshal(new File(fileName))).getValue();
	}
	private DepManType getDepartmentManagers(String fileName) throws JAXBException{
		return (DepManType)((JAXBElement) depManUnmarsh.unmarshal(new File(fileName))).getValue();
	}
	private DepartmentsType getDepartments(String fileName) throws JAXBException{
		return (DepartmentsType)((JAXBElement) departmentsUnmarsh.unmarshal(new File(fileName))).getValue();
	}
	private EmployeesType getEmployees(String fileName) throws JAXBException{
		return (EmployeesType)((JAXBElement) employeeUnmarsh.unmarshal(new File(fileName))).getValue();
	}
	
	public void addEmployees(String fileName) throws JAXBException{
		List <jaxb.employees.RowType> employeesList =  getEmployees(fileName).getRow();
		for(jaxb.employees.RowType r : employeesList){
			Employee e = new Employee(r.getEmpNo().longValue(), r.getBirthDate().toGregorianCalendar(), 
					r.getFirstName(), r.getLastName(), r.getGender(), r.getHireDate().toGregorianCalendar());
			Employee.add(e);
		}
		
	}
	public void addContactInfo(String fileName) throws JAXBException{
		List<InfoType> contactList = getContactInfo(fileName).getRow();
		for(InfoType i : contactList){
			Employee e =Employee.find(i.getEmpNo().longValue());
			e.addContactInfo(i.getEmail());
		}
	}
	public void addDepartments(String fileName) throws JAXBException{
		List<DepartmentType> departmentsList = getDepartments(fileName).getDepartment();
		for(DepartmentType d : departmentsList){
			Department dep = new Department(d.getDeptNo(), d.getDeptName());
			Department.add(dep);
		}
		
	}
	public void addDepartmentEmployees(String fileName) throws JAXBException{
		List<DemployeeType> depemployeeList = getDepartmentEmployee(fileName).getDemployee();
		for(DemployeeType d : depemployeeList){
			DepartmentEmp demp = new DepartmentEmp(Employee.find(d.getEmpNo().longValue()), Department.findByNum(d.getDeptNo()),
					d.getFromDate().toGregorianCalendar(), d.getToDate().toGregorianCalendar());
			DepartmentEmp.add(demp);
		}
	}
	public void addDepartmentManagers(String fileName) throws JAXBException{
		List<jaxb.departmentmanagers.RowType> depManList = getDepartmentManagers(fileName).getRow();
		for(jaxb.departmentmanagers.RowType r : depManList){
			DepartmentManager dman = new DepartmentManager(Employee.find(r.getEmpNo().longValue()), Department.findByNum(r.getDeptNo()),
					r.getFromDate().toGregorianCalendar(), r.getToDate().toGregorianCalendar());
			DepartmentManager.add(dman);
		}
	}
	
	public static void main(String args []) throws JAXBException{
		CreateDatabase.createDB();
		EmployeesUnmarshaller e = new EmployeesUnmarshaller();
		
		BufferedReader stdin =new BufferedReader(new InputStreamReader(System.in));
		String command;
		String filepath;
		do{
			System.out.println("Which Table do you wish to insert into?\n\t\tEmployees, Departments, Contact info, Department emps, Department managers");
			try {
				command  = stdin.readLine();
			} catch (IOException e1) {
				command = "?";
			}
			if(command.equalsIgnoreCase("Employees")){
				try {
					System.out.println("Enter path to employees xml file: ");
					filepath  = stdin.readLine();
					e.addEmployees(filepath);
				}catch(JAXBException e1) {
					System.out.println("File doesnt exist, make sure to use proper file path.\n " +
							"if looking for included xml doc, use path 'xml/employees.xml'");
				}
				catch (Exception e2) {
					System.out.println("An error has occured. Employee may already exist");
				}
			}
			else if(command.equalsIgnoreCase("Departments")){
				try {
					System.out.println("Enter path to Departments xml file: ");
					filepath  = stdin.readLine();
					e.addDepartments(filepath);
				} catch(JAXBException e1) {
					System.out.println("File doesnt exist, make sure to use proper file path.\n " +
							"if looking for included xml doc, use path 'xml/employees.xml'");
				}
				catch (Exception e2) {
					System.out.println("An error has occured. Department number may already exists");
				}
			}
			else if (command.equalsIgnoreCase("Contact info")){
				try {
					System.out.println("Enter path to contact info xml file: ");
					filepath  = stdin.readLine();
					e.addContactInfo(filepath);
				} catch(JAXBException e1) {
					System.out.println("File doesnt exist, make sure to use proper file path.\n " +
							"if looking for included xml doc, use path 'xml/employees.xml'");
				}
				catch (Exception e2) {
					System.out.println("An error has occured. It's possible that either the contact info already exists for\n" +
							"employee or employee doesnt exist. Make sure to add employees first");
				}
			}
			else if (command.equalsIgnoreCase("Department emps")){
				try {
					System.out.println("Enter path to Department emps xml file: ");
					filepath  = stdin.readLine();
					e.addDepartmentEmployees(filepath);
				} catch(JAXBException e1) {
					System.out.println("File doesnt exist, make sure to use proper file path.\n " +
							"if looking for included xml doc, use path 'xml/employees.xml'");
				}
				catch (Exception e2) {
					System.out.println("An error has occured. Make sure that departments and Employees \n" +
							"has been loaded. Employees may also already be in the table");
				}
			}
			else if(command.equalsIgnoreCase("Department managers")){
				try {
					System.out.println("Enter path to Department managers xml file: ");
					filepath  = stdin.readLine();
					e.addDepartmentManagers(filepath);
				} catch(JAXBException e1) {
					System.out.println("An error has occured. Make sure that departments and Employees \n" +
							"has been loaded. Managers may also be in the table");
				}
				catch (Exception e2) {
					e2.printStackTrace();
				}
			}
			else if(!command.equalsIgnoreCase("quit")){
				System.out.println("type 'quit' to quit");
				
			}
			
		}
		while(!command.equalsIgnoreCase("quit"));
	       
	}
}
